package com.Cfeng.XiaohuanChat.security;

import com.Cfeng.XiaohuanChat.entity.ChatUser;
import com.Cfeng.XiaohuanChat.entity.ChatUserAuthority;
import com.Cfeng.XiaohuanChat.entity.ChatUserRole;
import com.Cfeng.XiaohuanChat.repository.ChatUserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author Cfeng
 * @date 2022/8/7
 * 这里的UserDetail为登录的验证service，可以将之前的ChatUser放入一起，但是为了显示区别，安全service单独
 * 它和Service包中的一起操作repository，但是该类只是query
 */

@Service
@RequiredArgsConstructor
public class SecurityUserDetailServiceImpl implements UserDetailsService {

    private final ChatUserRepository userRepository;

    //密码匹配自动完成，返回一个User即可
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        ChatUser currentUser = userRepository.findByUserName(username);
        if(Objects.isNull(currentUser)) {
            throw new BadCredentialsException("用户名不存在");
        }
        return new User(currentUser.getUserName(),currentUser.getUserPwd(),this.getGrantedAuthorities(currentUser));
    }

    private List<GrantedAuthority>  getGrantedAuthorities(ChatUser user) {
        //角色和权限一起
        List<GrantedAuthority> authorityList = new ArrayList<>();

        for(ChatUserRole role : user.getRoles()) {
            authorityList.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
            for(ChatUserAuthority authority : role.getAuthorities()) {
                authorityList.add(new SimpleGrantedAuthority(authority.getAuthName()));
            }
        }

        return authorityList;
    }
}
